﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using nHydrate.GeoLocation.Interfaces;
using Widgetsphere.Autos.API;

namespace Widgetsphere.Autos.Websitev2.UserControls
{
    public partial class MapControl : System.Web.UI.UserControl
    {
        private Dictionary<GeoLocationCode, string> _mapPoints = new Dictionary<GeoLocationCode, string>();

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (ConfigHelper.AllowMaps)
            {
                //Insert the Google include script
                var includeScript = new Literal();
                includeScript.Text = "<script src='https://maps.googleapis.com/maps/api/js?key=AIzaSyCkjwXtksSvuOACoPgNl9JW2RkkmowxDUc&sensor=true' type='text/javascript'></script>";
                this.Page.Header.Controls.Add(includeScript);
            }
            else
            {
                this.Visible = false;
            }
        }

        #region Property Imeplementations

        private int _zoomLevel = 5;
        public int ZoomLevel
        {
            get { return _zoomLevel; }
            set { _zoomLevel = value; }
        }

        #endregion

        #region Methods

        public void Populate(Widgetsphere.Autos.API.FacetedNavigation.ListingResults results)
        {
            this.Populate(results, true);
        }

        public void Populate(Widgetsphere.Autos.API.FacetedNavigation.ListingResults results, bool useHeaderLink)
        {
            if (!ConfigHelper.AllowMaps) return;

            //Loop and load all geo-coded entries
            var geoCodeList = new List<GeoLocationCode>();
            foreach (var record in results.RecordList)
            {
                var state = GetRValue(record.State);
                var zip = GetRValue(record.ZIP);
                var description = GetRValue(record.Description);
                var latitude = string.Empty;
                var longitude = string.Empty;

                double distance = 0;
                if (record.Location != null)
                {
                    latitude = GetRValue(record.Location.Latitude);
                    longitude = GetRValue(record.Location.Longitude);
                    if (record.Location.Distance != null)
                        distance = record.Location.Distance.Value;
                }

                double latitudeValue;
                double longitudeValue;
                double.TryParse(latitude, out latitudeValue);
                double.TryParse(longitude, out longitudeValue);

                GeoLocationCode code;
                if (geoCodeList.GeoLocationCodeListContains(latitudeValue, longitudeValue))
                {
                    code = geoCodeList.GetGeoLocationCodeFromList(latitudeValue, longitudeValue);
                }
                else
                {
                    code = new GeoLocationCode { Longitude = longitudeValue, Latitude = latitudeValue };
                    if ((code.Latitude != 0) && (code.Longitude != 0))
                        geoCodeList.Add(code);
                }

                if ((code.Latitude != 0) && (code.Longitude != 0))
                {
                    var headerLink = record.Title;

                    if (description != string.Empty)
                    {
                        var d = Utilities.StripHtmlTags(description)
                            .ConvertLineBreaksToHTML();
                        const int MAXTEXT = 400;
                        if (d.Length > MAXTEXT)
                        {
                            d = d.Substring(0, MAXTEXT) + "...";
                        }
                        d = d.Replace("'", "&apos;");
                        code.Description = "<div class=\"map-text\"><hr style=\"margin:0px 0px 10px 0px;padding:0px;\" />" + d + "</div>";
                    }

                    var tableText = string.Empty;
                    tableText += "<h3>";
                    if (useHeaderLink)
                    {
                        var url = "/auto-detail.aspx?id=" + record.AutoID;
                        var urlLink = "<a style=\"font-size:1em;font-weight:bold;text-overflow:ellipsis;\" class=\"map-link\"  href=\"" + url + "\">" + Server.HtmlEncode(Server.HtmlEncode(headerLink)) + "</a>";
                        if (!_mapPoints.ContainsKey(code)) _mapPoints.Add(code, urlLink);
                        tableText += urlLink;
                    }
                    else
                    {
                        tableText += Server.HtmlEncode(headerLink);
                    }
                    tableText += "</h3>";
                    tableText += Server.HtmlEncode(state) + " " + Server.HtmlEncode(zip);
                    code.Text = record.Title;
                }
            }

            if (geoCodeList.Count == 0)
                Visible = false;
            else
                LoadMap(geoCodeList);
        }

        private void LoadMap(List<GeoLocationCode> geoCodeList)
        {
            //Get the map center
            var center = geoCodeList.GetGeoLocationCodeCenter();

            //If there are no items then do not show map
            if (center == null) return;

            //Build the script to show markers
            var sb = new StringBuilder();
            sb.AppendLine("<script type=\"text/javascript\">");
            sb.AppendLine("<!--");

            sb.AppendLine("var infowindow = null;");

            sb.AppendLine("  infowindow = new google.maps.InfoWindow({");
            sb.AppendLine("      content: ''");
            sb.AppendLine("  });");

            sb.AppendLine("function addMapPoint(map,point,contentString,title) {");
            sb.AppendLine("  var marker = new google.maps.Marker({");
            sb.AppendLine("      position: point,");
            sb.AppendLine("      map: map,");
            sb.AppendLine("      title: title");
            sb.AppendLine("  });");
            sb.AppendLine("  google.maps.event.addListener(marker, 'click', function() {");
            sb.AppendLine("     infowindow.close(map, marker);");
            sb.AppendLine("     infowindow.setContent(contentString);");
            sb.AppendLine("     infowindow.open(map,marker);");
            sb.AppendLine("  });");
            sb.AppendLine("}");

            sb.AppendLine("    function initialize() {");
            sb.AppendLine("        var mapOptions =");
            sb.AppendLine("        {");
            sb.AppendLine("            scrollwheel: false,");
            sb.AppendLine("            zoom: " + ZoomLevel + ",");
            sb.AppendLine("            center: new google.maps.LatLng(" + center.Latitude + ", " + center.Longitude + "),");
            sb.AppendLine("            mapTypeId: google.maps.MapTypeId.ROADMAP,");
            sb.AppendLine("        };");
            sb.AppendLine("        var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);");

            sb.AppendLine("var point;");
            sb.AppendLine("var contentString;");
            sb.AppendLine("var title;");
            foreach (var code in geoCodeList.Where(x => x != null))
            {
                var urlLink = string.Empty;
                if (_mapPoints.ContainsKey(code)) urlLink = _mapPoints[code];
                else urlLink = code.Text;
                urlLink = "<h4>" + urlLink + "</h4>";

                sb.AppendLine("  point = new google.maps.LatLng(" + code.Latitude + ", " + code.Longitude + ");");
                sb.AppendLine("  contentString = '<div>" + urlLink + "</div><div>" + code.Description + "<div>';");
                sb.AppendLine("  title = '" + code.Text + "';");
                sb.AppendLine("  addMapPoint(map,point,contentString, title);");
            }

            sb.AppendLine("    };");
            sb.AppendLine("    google.maps.event.addDomListener(window, 'load', initialize);");
            sb.AppendLine("-->");
            sb.AppendLine("</script>");

            Page.ClientScript.RegisterStartupScript(typeof(string), "startup", sb.ToString());
        }

        private string GetRValue(string value)
        {
            return GetRValue(value, string.Empty);
        }

        private string GetRValue(string value, string defaultValue)
        {
            if (value == null)
                return defaultValue;
            else
                return value;
        }

        private string GetRValue(double? value)
        {
            return GetRValue(value, 0);
        }

        private string GetRValue(double? value, double defaultValue)
        {
            if (value == null)
                return defaultValue.ToString();
            else
                return value.ToString();
        }

        #endregion


    }
}